/**
 * Copyright (c), 2012~2020 iot.10086.cn All Rights Reserved
 *
 * @file main.c
 * @brief
 */
 /******************************main.c****************************************/
#include "common.h"
#include "data_types.h"
#include "plat_time.h"
#include "tm_api.h"
#include "tm_data.h"
#include "tm_user.h"
/*****************************************************************************/
/** OneNET平台产品ID ffU37A69Yb */
#define TM_PRODUCT_ID "Rr650S1erb"

/** 设备唯一识别码，产品内唯一 test1device */
#define TM_DEVICE_NAME "csn"

/** 认证信息--设备key QX8LW79HOXNh96cjFVlNO9mXk/GFcZ9xQRkNyQGD9UM=  */
#define TM_ACCESS_KEY "n9k5G1nrL6XTR7HhlauNizsPRed9yQ1bHX3x62eR598="

/** token有效时间，默认设置为2030年12月*/
#define TM_EXPIRE_TIME 1924833600
/*****************************************************************************/
/******************************wsnserial.h************************************/
#define WORDLEN		32		//其他名称长度32字节（16个汉字）
struct serial_config
{
	unsigned char serial_dev[WORDLEN];
	unsigned int serial_speed;
	unsigned char databits;
	unsigned char stopbits;
	unsigned char parity;
};
/******************************wsnserial.c*******************************/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <signal.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include"pthread.h"
#include <stddef.h>

int nread=0;
char Recbuff[1024];
int sRecDataLen = 0;


int  temp_value=0; 
int  light_value=0;
int  humi_value=0;
int  yanwu_value=0;
int  co_value=0;
bool voice_value=0;
bool body_value=0;

struct serial_config serialread;

static int serial_fd;

int speed_arr[] = {B230400, B115200, B57600, B38400, B19200, B9600, B4800, B2400, B1200, B300,
		   B38400, B19200, B9600, B4800, B2400, B1200, B300};

int name_arr[] = {230400, 115200, 57600, 38400, 19200, 9600, 4800, 2400, 1200, 300,
		  38400, 19200, 9600, 4800, 2400, 1200, 300};

void ScanData();
void DateDispose(char Packet[],int PacketLen);
void set_speed(int fd,int speed);
int set_Parity(int fd,int databits,int stopbits,int parity);
int OpenDev(char *Dev);
int serial_init(void);
float ScanADdata(char byte9);
int PressData(char byte);
int RainData(char byte);
float WaterData(char byte);
float ultrasonicData(char byte);
void * fbl_malloc(int len, char * str);
char XorVerify(char BytesCMD[]);

int main(int arg, char* argv[])
{
    struct tm_downlink_tbl_t dl_tbl;
    int ret=0;
   // int      temp=0;int      power=100;
    int result=0;
    dl_tbl.prop_tbl      = tm_prop_list;
    dl_tbl.prop_tbl_size = tm_prop_list_size;
    dl_tbl.svc_tbl       = tm_svc_list;
    dl_tbl.svc_tbl_size  = tm_svc_list_size;

        serial_init();
	printf("wsn-serial test starting!!!!!!\n");
	int i;
	char buff[1024];
    /** 设备初始化*/
    ret = tm_init(&dl_tbl);
    CHECK_EXPR_GOTO(ERR_OK != ret, _END, "ThingModel init failed!\n");
    logi("ThingModel init ok");

    /** 设备登录*/
    ret = tm_login(TM_PRODUCT_ID, TM_DEVICE_NAME, TM_ACCESS_KEY, TM_EXPIRE_TIME, 3000);
    CHECK_EXPR_GOTO(ERR_OK != ret, _END, "ThingModel login failed!");
    logi("ThingModel login ok");
	
	
	
    while (1) {
        if (0 != (ret = tm_step(200))) {
            logi("ThingModel tm_step failed,ret is %d",ret);
            break;
        }        
		/*处理接收并判断相应传感器对应的数值*/
	if((nread = read(serial_fd,buff,1024))>0)
	{
		buff[nread] = '\0';			
		for(i=0;i<nread;i++)
		{
			Recbuff[sRecDataLen + i] = buff[i];
		}
		sRecDataLen = sRecDataLen + nread;
		 ScanData();
                                
	}
                 
    }

    /** 设备注销*/
    tm_logout(3000);
_END:
    return 0;
}
void set_speed(int fd,int speed)
{
	int i;
	int status;
	struct termios Opt;
	//struct termios oldOpt;
	tcgetattr(fd, &Opt);
//	printf("serialread.speed is %d\n",serialread.serial_speed);
	for( i = 0; i < sizeof(speed_arr)/sizeof(int); i++)
	{
		if(speed == name_arr[i])
		{
			tcflush(fd, TCIOFLUSH);
			cfsetispeed(&Opt, speed_arr[i]);
			cfsetospeed(&Opt, speed_arr[i]);
			status = tcsetattr(fd, TCSANOW, &Opt);
			if(status != 0)
				perror("tcsetattr fd1");
				return;
		}
		tcflush(fd, TCIOFLUSH);
	}
}

int set_Parity(int fd,int databits,int stopbits,int parity)
{
	struct termios options;
	//struct termios oldoptions;
	if(tcgetattr(fd, &options) != 0)
	{
		perror("SetupSerial 1");
		return(FALSE);
	}

	//options.c_cflag |= (CLOCAL|CREAD);
	options.c_cflag &=~CSIZE;
//	printf("serialread.databits is %d\n",serialread.databits);
	switch(databits)
	{
		case 7:
			options.c_cflag |= CS7;
			break;
		case 8:
			options.c_cflag |= CS8;
			break;
		default:
			fprintf(stderr,"Unsupported data size\n");
			return(FALSE);
	}
//	printf("serialread.parity is %c\n",serialread.parity);
	switch(parity)
	{
		case 'n':
		case 'N':
			options.c_cflag &= ~PARENB;
			options.c_iflag &= ~INPCK;
			break;
		case 'o':
		case 'O':
			options.c_cflag |= (PARODD | PARENB);
			options.c_iflag |= INPCK;
			break;
		case 'e':
		case 'E':
			options.c_cflag |= PARENB;
			options.c_cflag &= ~PARODD;
			options.c_iflag |= INPCK;
			break;
		case 'S':
		case 's':  /*as no parity*/
			options.c_cflag &= ~PARENB;
			options.c_cflag &= ~CSTOPB;
			break;
		default:
			fprintf(stderr, "Unsupported parity\n");
			return(FALSE);
	}
//	printf("serialread.stopbits is %d\n",serialread.stopbits);
	switch(stopbits)
	{
		case 1:
			options.c_cflag &= ~CSTOPB;
			break;
		case 2:
			options.c_cflag |= CSTOPB;
			break;
		default:
			fprintf(stderr,"Unsupported stop bits\n");
			return(FALSE);
	}
	if(parity != 'n'&& parity != 'N')
		options.c_iflag |= INPCK;

	options.c_cflag &= ~CRTSCTS;
	options.c_iflag &= ~IXOFF;
	options.c_iflag &= ~IXON;
	if(parity != 'n'&& parity != 'N')
                options.c_iflag |= INPCK;
	tcflush(fd, TCIOFLUSH);
	
//	options.c_iflag |= IGNPAR|ICRNL;
	options.c_lflag &= ~(ICANON|ECHO|ECHOE|ISIG);
//	options.c_oflag |= OPOST; 
	options.c_oflag &= ~OPOST;
	options.c_iflag &= ~(ICRNL|IGNCR); 
//	options.c_iflag &= ~(IXON|IXOFF|IXANY);
	options.c_cc[VTIME] = 0;        //150;                  //15 seconds
        options.c_cc[VMIN] = 0;

	tcflush(fd, TCIFLUSH);
	if(tcsetattr(fd, TCSANOW, &options) != 0)
	{
		perror("SetupSerial 3");
		return(FALSE);
	}
	return(TRUE);
}

int OpenDev(char *Dev)
{
	int fd = open(Dev, O_RDWR);
	if(-1 == fd)
	{
		perror("Can't Open Serial Port");
		return -1;
	}
	else
		return fd;
}
int serial_init(void)
{
	char *Dev = "/dev/ttySAC1";

	int i;

	serial_fd = OpenDev(Dev);

	if(serial_fd > 0)
		set_speed(serial_fd,115200);
	else
	{
		printf("Can't Open Serial Port!\n");
		exit(0);
	}
	if(set_Parity(serial_fd,8,1,'N') == FALSE)
	{
		printf("Set parity Error\n");
		exit(1);
	}
	return 0;
}

float ScanADdata(char byte9)
{
	float ADdata;
	if(byte9 > 0xf0)
		ADdata = 0;
	else if(byte9 > 0x80)
		ADdata = 3.3;
	else 
		ADdata = (3.3/127)*byte9;
	
	return ADdata;
}

int PressData(char byte)
{
	int temp = 0;
	if(byte > 36)

		temp = (byte-34)*200/18;
	else
		temp = 0;
	return temp;
}
int RainData(char byte)
{
	if(byte > 11)
		return 1;
	else
		return 0;
}

float WaterData(char byte)
{	
	float WaterData;
	if(byte >0)
		WaterData = (byte+3)/7.5;	
	else
		WaterData = 0;
	return WaterData;
}

float ultrasonicData(char byte)
{
	float ultrasonicData;
	
	ultrasonicData = 0.0544*byte;
	
	return ultrasonicData;
}

void * fbl_malloc(int len, char * str)
{
	void * ptr = malloc(len);
	if(ptr == 0)
		printf("%s Failed (len = %d)!!!\n", str, len);
	return ptr;
}

char XorVerify(char BytesCMD[])
{
	char checksum = BytesCMD[1];
	int i;
	for (i = 1; i < BytesCMD[1]+1; i++)
	{
		checksum ^= BytesCMD[i+1];
	}
	return checksum;
}
void ScanData()
{
	
	int source_addr,father_addr;
	char test,byteCheck;
	char PacketBuff[50];
	int PacketLen;

	struct wsn_comm_pkg *pkt = 0;
	if(sRecDataLen > 0)
	{
		//printf("RecDataLen : %d\n",sRecDataLen);
		int sFirstPosition = 0;
		while(sFirstPosition < sRecDataLen)
		{
			//printf("sFirstPosition: %d\n",sFirstPosition);
			if(Recbuff[sFirstPosition] == 0x2)  
			{
				PacketLen = Recbuff[sFirstPosition + 1]+3;
				//printf("PacketLen : %d\n",PacketLen);
				if(PacketLen <= sRecDataLen -sFirstPosition)  
				{
					//printf("PacketBuff=");
					int i;
					for(i = 0; i < PacketLen; i++){   
						PacketBuff[i] = Recbuff[sFirstPosition + i];
						//printf("%02x ",PacketBuff[i]);
					}
					//printf("\n");
					
					DateDispose(PacketBuff,PacketLen);
						
					for(i = 0; i < sRecDataLen - sFirstPosition - PacketLen; i++)
					{
						Recbuff[i] = Recbuff[sFirstPosition + PacketLen+i];
					}
					sRecDataLen -= PacketLen + sFirstPosition;
				}
				return;
			}
			else
			{
				sFirstPosition++;
			}
		}
		sRecDataLen = 0;
	}
}

void DateDispose(char Packet[],int PacketLen) {
	   
	int SensorType = 0;
	 if (XorVerify(Packet) == Packet[PacketLen - 1]) {
     		if( (Packet[2] == 0xB8) && (Packet[3] == 0x47) )//Zigbee
		{
			SensorType = Packet[10] & 0x3f;	
			if( SensorType == 0x06 )//超声波:6
			{
				printf("\nZigbee---超声波: %.4f 米\n",ultrasonicData(Packet[11]));			
			}
			if( SensorType == 0x0e )//压力:14
			{
				printf("\nZigbee---压力: %d g\n",PressData(Packet[11]));
			}
		}
		else if( (Packet[2] == 0xBE) && (Packet[3] == 0x41) )//Lora
		{
			SensorType = Packet[9];	
			if( SensorType == 0x0B )//一氧化碳:0x0b
			{
				printf("\nLora---一氧化碳: %d\n",Packet[10]);
                                
                                co_value=Packet[10];
                            //time_delay_ms(3000); 	
                            tm_prop_int32_notify(NULL,co_value,"CO",3000);
                               
			}
			if( SensorType == 0x04 )//烟雾:0x04
			{
				printf("\nLora---烟雾: %d\n",Packet[10]);
                                yanwu_value=Packet[10];
                             // time_delay_ms(3000); 	
                               tm_prop_int32_notify(NULL,yanwu_value,"MQ2",3000);

			}
		}
		else if( (Packet[2] == 0xBA) && (Packet[3] == 0x45) )//Wifi
		{
			SensorType = Packet[9];	
			if( SensorType == 0x02 )//光照:0x02
			{
				printf("\nWifi---光照: %d lux\n",Packet[10]);
                                light_value=Packet[10];
                            // time_delay_ms(3000); 	
                                tm_prop_int32_notify(NULL,light_value,"light",3000);
                              			
			}
			if( SensorType == 0x07 )//三轴:0x07
			{
				printf("\nWifi---三轴: X轴=%d ,Y轴=%d ,Z轴=%d\n",Packet[10],Packet[11],Packet[12]);	
			}
			if( SensorType == 0x03 )//振动:0x03
			{
				if( Packet[10] == 0x01 )
				{
					printf("\nWifi---振动: 有\n");
				}
				if( Packet[10] == 0x00 )
				{
					printf("\nWifi---振动: 无\n");
				}			
			}
		}
		else if( (Packet[2] == 0xBB) && (Packet[3] == 0x44) )//Ble4
		{
			SensorType = Packet[9];	
			if( SensorType == 0x00 )//温湿度:0
			{
				printf("\nBle4---温湿度: 温度=%d℃ ,湿度=%d%\n",Packet[10],Packet[11]);
                                temp_value=Packet[10];
                                humi_value=Packet[11];
                       //  time_delay_ms(3000); 	
                          tm_prop_int32_notify(NULL,temp_value,"Temp",3000);
                         // time_delay_ms(1000); 
                          tm_prop_int32_notify(NULL,humi_value,"Humi",3000);
                                			
			}
			if( SensorType == 0x01 )//人体:1
			{
				if( Packet[10] == 0x01 )
				{
					printf("\nBle4---人体: 有\n");
                                        body_value=true;
                                        
                                        
				}
				if( Packet[10] == 0x00 )
				{
					printf("\nBle4---人体: 无\n");
                                        body_value=false;      
				}
                            // time_delay_ms(3000); 	
                                tm_prop_bool_notify(NULL, body_value, "body", 3000);
			}
			if( SensorType == 0x11 )//声音:17
			{
				if( Packet[10] == 0x01 )
				{
					printf("\nBle4---声音: 有\n");
                                        voice_value=true;
				}
				if( Packet[10] == 0x00 )
				{
					printf("\nBle4---声音: 无\n");
                                        voice_value=false;
				}
                            //  time_delay_ms(3000); 	
                                tm_prop_bool_notify(NULL, voice_value, "voice", 3000);
			}
		}
		else{
			
		}
     
 }
}	

 
